<?php
/**
 * vim: et ts=4 sts=4 sw=4 fdm=marker
 *
 * 生成验证码---仿UCHOME 
 *
 * @author	wang Penghai <china_php@hotmail.com>
 * @copyright 2008 5e6d Corporation.
 * @version   $Id:$
 */


class pf_codeimage{

	/*{{{code*/
	const DB_DRIVER_NO_EXIST = '300001';
	/*}}}*/

	/*{{{member*/
	
	/**
	 * 生成图片的函数是否可用
	 */
	protected $_img_func_on = true;

	/**
	 * 生成jpeg,png的函数是否可用
	 */
	protected $_img_func = array('jpeg'=>false, 'png'=>false);
	/**
	 * 生成图片参数
	 */
	protected $_img_params = array('width' => 100, 'height' => 40, 'adulterate' => 1, 'angle' => 0, 'shadow' => 1);
	/**
	 * 生成图片参数
	 */
	protected $_c = array();
	/**
	 * 生成图片参数
	 */
	protected $_im = '';
	/*}}}*/

	/*{{{ function */
	/*{{{ public __construct()*/
	
	/**
	 * 构造函数--
	public function __construct() {
	}
	 */

	/*}}}*/
	/*{{{ public function seccode()*/

	/**
	 * 生成验证码
	 *
	 * @return 
	 */
	public function seccode()
	{
		$this->_auth_check();
		if (false === $this->_img_func) {
			$image = $this->_mkbmp();			
			return $image;
		}

		$seccode = $this->_mkseccode();
		$bgcontent = $this->_mkbackground();
		//干扰码
		$this->_mkadulterate();
		
	}

	/*}}}*/
	/*{{{ protected function _auth_check()*/
	/**
	 * 检测image函数是否可有 
	 * 
	 * @return void 
	 */ 
	protected function _auth_check()
	{
		$img_funs = array(
					'imagecreate',
					'imagecolorset',
					'imagecopyresized',
					'imagecolorallocate',
					'imagechar',
					'imagecolorsforindex',
					'imageline',
					'imagecreatefromstring',
			);
		foreach ($img_funs as $key => $val) {
			if (!function_exists($val)) {
				$this->_img_func_on = false;
				break;
			}
		}
		
		$img_type = array(
				'png' => 'imagepng',
				'jpeg' => 'imagejpeg',
				'gif' => 'imagegif',
			);

		foreach ($img_type as $key => $val) {
			if (function_exists($val)) {
				$this->_img_func = array($key => true);				
			}
		}
	}
	
	/*}}}*/
	/*{{{ protected function set_params()*/

	/**
	 * 设置参数
	 *
	 * @param array('width'=>40,	
	 *			   'height' => 40,
	 *			   'adulterate' => '1',//是否需要干扰码
	 *			   'angle' => '0',//角度
	 *			   'shadow' => '1',//阴影
	 *		  );
	 *
	 * @return void
	 */
	public function set_params($argvs)
	{
		if (isset($argvs['width'])) {
			$this->_img_params['width'] = (int)$argvs['width'];
		}

		if (isset($argvs['height'])) {
			$this->_img_params['height'] = (int)$argvs['height'];
		}

		if (isset($argvs['adulterate'])) {
			$this->_img_params['adulterate'] = (int)$argvs['adulterate'];
		}

		if (isset($argvs['angle'])) {
			$this->_img_params['angle'] = (int)$argvs['angle'];
		}

		if (isset($argvs['shadow'])) {
			$this->_img_params['shadow'] = (int)$argvs['shadow'];
		}
	}

	/*}}}*/
	/*{{{ protected function _mksecode()*/

	/**
	 * 生成验证数据
	 *
	 * @see inc/function.php
	 * @return void
	 */
	protected function _mkseccode() {
		$seccode = random(6, 1);//在inc function.php 里定义
		$s = sprintf('%04s', base_convert($seccode, 10, 24));
		$seccode = '';
		$seccodeunits = 'BCEFGHJKMPQRTVWXY2346789';
		for($i = 0; $i < 4; $i++) {
			$unit = ord($s{$i});
			$seccode .= ($unit >= 0x30 && $unit <= 0x39) ? $seccodeunits[$unit - 0x30] : $seccodeunits[$unit - 0x57];
		}
		return $seccode;
	}

	/*}}}*/
	/*{{{ protected function _mkbackgroud()*/

	/**
	 * 生成背景
	 *
	 * @return void
	 */
	protected function _mkbackground() 
	{
		$c = array();
		$im = imagecreatetruecolor($this->_img_params['width'], $this->_img_params['height']);//新建一个真彩色图片，应该是黑的。
		$backgroundcolor = imagecolorallocate($im, 255, 255, 255);//为一副图片分配颜色

		for($i = 0;$i < 3;$i++) {
			$start[$i] = mt_rand(200, 255);
			$end[$i] = mt_rand(100, 245);
			$step[$i] = ($end[$i] - $start[$i]) / $this->_img_params['width'];
			$c[$i] = $start[$i];
		}
		//$color = imagecolorallocate($im, 235, 235, 235);
		for($i = 0;$i < $this->_img_params['width'];$i++) {
			$color = imagecolorallocate($im, $c[0], $c[1], $c[2]);
			imageline($im, $i, 0, $i-$this->_img_params['angle'], $this->_img_params['height'], $color);
			$c[0] += $step[0];
			$c[1] += $step[1];
			$c[2] += $step[2];
		}
		$c[0] -= 20;
		$c[1] -= 20;
		$c[2] -= 20;

		ob_start();
		if(function_exists('imagepng')) {
			imagepng($im);
		} else {
			imagejpeg($im, '', 100);// 以 JPEG 格式将图像输出到浏览器或文件
		}
	   // imagedestroy($im);
		$bgcontent = ob_get_contents();
		ob_clean();

		$this->_c = $c;
		$this->_im = $im;
		//return $bgcontent;
	}

	/*}}}*/
	/*{{{ protected function _mkadulterate()*/

	/**
	 * 生成干扰码
	 *
	 *
	 */
	protected function _mkadulterate()
	{
		$c = $this->_c;
		$seccodedata = $this->_img_params;
		$im = $this->_im;
		$linenums = $seccodedata['height'] / 10;
		for($i=0; $i <= $linenums; $i++) {
			$color = imagecolorallocate($im, $c[0], $c[1], $c[2]);
			$x = mt_rand(0, $seccodedata['width']);
			$y = mt_rand(0, $seccodedata['height']);
			if(mt_rand(0, 1)) {
				imagearc($im, $x, $y, mt_rand(0, $seccodedata['width']), 
						mt_rand(0, $seccodedata['height']), mt_rand(0, 360), mt_rand(0, 360), $color);
			} else {
				imageline($im, $x, $y, $linex + mt_rand(0, 20), $liney + mt_rand(0, mt_rand($seccodedata['height'], 
								$seccodedata['width'])), $color);
			}
		}
		$this->_im = $im;

	}

	/*}}}*/
	/*{{{ protected function _mkgiffont()*/
	
	/**
	 * 合并文字信息
	 *
	 */
	protected function seccode_giffont() 
	{
		$c = $this->_c;
		$seccodedata = $this->_img_params;
		$im = $this->_im;

		$seccodedir = array();
		if(function_exists('imagecreatefromgif')) {
			$seccoderoot = 'image/seccode/';
			$dirs = opendir($seccoderoot);
			while($dir = readdir($dirs)) {
				if($dir != '.' && $dir != '..' && file_exists($seccoderoot.$dir.'/9.gif')) {
					$seccodedir[] = $dir;
				}
			}
		}
		$widthtotal = 0;
		for($i = 0; $i <= 3; $i++) {
			$imcodefile = $seccodedir ? $seccoderoot.$seccodedir[array_rand($seccodedir)].'/'.strtolower($seccode[$i]).'.gif' : '';
			if(!empty($imcodefile) && file_exists($imcodefile)) {
				$font[$i]['file'] = $imcodefile;
				$font[$i]['data'] = getimagesize($imcodefile);
				$font[$i]['width'] = $font[$i]['data'][0] + mt_rand(0, 6) - 4;
				$font[$i]['height'] = $font[$i]['data'][1] + mt_rand(0, 6) - 4;
				$font[$i]['width'] += mt_rand(0, $seccodedata['width'] / 5 - $font[$i]['width']);
				$widthtotal += $font[$i]['width'];
			} else {
				$font[$i]['file'] = '';
				$font[$i]['width'] = 8 + mt_rand(0, $seccodedata['width'] / 5 - 5);
				$widthtotal += $font[$i]['width'];
			}
		}
		$x = mt_rand(1, $seccodedata['width'] - $widthtotal);
		for($i = 0; $i <= 3; $i++) {
			if($font[$i]['file']) {
				$imcode = imagecreatefromgif($font[$i]['file']);
				$y = mt_rand(0, $seccodedata['height'] - $font[$i]['height']);
				if($seccodedata['shadow']) {
					$imcodeshadow = $imcode;
					imagecolorset($imcodeshadow, 0 , 255 - $c[0], 255 - $c[1], 255 - $c[2]);
					imagecopyresized($im, $imcodeshadow, $x + 1, $y + 1, 0, 0, $font[$i]['width'], $font[$i]['height'], 
																			$font[$i]['data'][0], $font[$i]['data'][1]);
				}
				imagecolorset($imcode, 0 , $c[0], $c[1], $c[2]);
				imagecopyresized($im, $imcode, $x, $y, 0, 0, $font[$i]['width'], $font[$i]['height'], $font[$i]['data'][0],
																										 $font[$i]['data'][1]);
			} else {
				$y = mt_rand(0, $seccodedata['height'] - 20);
				if($seccodedata['shadow']) {
					$text_shadowcolor = imagecolorallocate($im, 255 - $c[0], 255 - $c[1], 255 - $c[2]);
					imagechar($im, 5, $x + 1, $y + 1, $seccode[$i], $text_shadowcolor);
				}
				$text_color = imagecolorallocate($im, $c[0], $c[1], $c[2]);
				imagechar($im, 5, $x, $y, $seccode[$i], $text_color);
			}
			$x += $font[$i]['width'];
		}
	}

	/*}}}*/
	/*{{{ protected function _mkbmp()*/
	/**
	 * 生成bmp图片
	 *
	 *
	 *
	 */
	protected function _mkbmp()
	{
		$numbers = array
			(
			 'B' => array('00','fc','66','66','66','7c','66','66','fc','00'),
			 'C' => array('00','38','64','c0','c0','c0','c4','64','3c','00'),
			 'E' => array('00','fe','62','62','68','78','6a','62','fe','00'),
			 'F' => array('00','f8','60','60','68','78','6a','62','fe','00'),
			 'G' => array('00','78','cc','cc','de','c0','c4','c4','7c','00'),
			 'H' => array('00','e7','66','66','66','7e','66','66','e7','00'),
			 'J' => array('00','f8','cc','cc','cc','0c','0c','0c','7f','00'),
			 'K' => array('00','f3','66','66','7c','78','6c','66','f7','00'),
			 'M' => array('00','f7','63','6b','6b','77','77','77','e3','00'),
			 'P' => array('00','f8','60','60','7c','66','66','66','fc','00'),
			 'Q' => array('00','78','cc','cc','cc','cc','cc','cc','78','00'),
			 'R' => array('00','f3','66','6c','7c','66','66','66','fc','00'),
			 'T' => array('00','78','30','30','30','30','b4','b4','fc','00'),
			 'V' => array('00','1c','1c','36','36','36','63','63','f7','00'),
			 'W' => array('00','36','36','36','77','7f','6b','63','f7','00'),
			 'X' => array('00','f7','66','3c','18','18','3c','66','ef','00'),
			 'Y' => array('00','7e','18','18','18','3c','24','66','ef','00'),
			 '2' => array('fc','c0','60','30','18','0c','cc','cc','78','00'),
			 '3' => array('78','8c','0c','0c','38','0c','0c','8c','78','00'),
			 '4' => array('00','3e','0c','fe','4c','6c','2c','3c','1c','1c'),
			 '6' => array('78','cc','cc','cc','ec','d8','c0','60','3c','00'),
			 '7' => array('30','30','38','18','18','18','1c','8c','fc','00'),
			 '8' => array('78','cc','cc','cc','78','cc','cc','cc','78','00'),
			 '9' => array('f0','18','0c','6c','dc','cc','cc','cc','78','00')
				 );

		foreach($numbers as $i => $number) {
			for($j = 0; $j < 6; $j++) {
				$a1 = substr('012', mt_rand(0, 2), 1).substr('012345', mt_rand(0, 5), 1);
				$a2 = substr('012345', mt_rand(0, 5), 1).substr('0123', mt_rand(0, 3), 1);
				mt_rand(0, 1) == 1 ? array_push($numbers[$i], $a1) : array_unshift($numbers[$i], $a1);
				mt_rand(0, 1) == 0 ? array_push($numbers[$i], $a1) : array_unshift($numbers[$i], $a2);
			}
		}

		$bitmap = array();
		for($i = 0; $i < 20; $i++) {
			for($j = 0; $j < 4; $j++) {
				$n = substr($seccode, $j, 1);
				$bytes = $numbers[$n][$i];
				$a = mt_rand(0, 14);
				array_push($bitmap, $bytes);
			}
		}

		for($i = 0; $i < 8; $i++) {
			$a = substr('012345', mt_rand(0, 2), 1) . substr('012345', mt_rand(0, 5), 1);
			array_unshift($bitmap, $a);
			array_push($bitmap, $a);
		}

		$image = pack('H*', '424d9e000000000000003e000000280000002000000018000000010001000000'.
				'0000600000000000000000000000000000000000000000000000FFFFFF00'.implode('', $bitmap));

		return $image;
	//	header('Content-Type: image/bmp');
	 //   echo $image;
	}
	/*}}}*/
	/*}}}*/
}
/*
$img = new pf_lib_codeimage;
$img->seccode();
*/